﻿#include "testdb.h"

void Testdb::initTestCase() {
    // 指定SQLite数据库名称
    QString dbName = "testDatabase.db";

    // 获取DatabaseManager实例并连接SQLite数据库
    DatabaseManager& dbManager = DatabaseManager::instance();
    dbManager.connectToSqlite(dbName);

    // 获取数据库实例
    QSqlDatabase db = dbManager.getDatabase();

    // 确认数据库连接是否成功打开
    if (!db.isOpen()) {
        //qDEbug() << "Failed to open database";
        QFAIL("Failed to open database");
    } else {
        //qDEbug() << "Database opened successfully";
    }

    // 清除现有表
    QSqlQuery query(db);
    QStringList tables = { "Authentication", "PurchaseOrder", "Finance", "EnterRecord", "Inventory" };
    for (const QString& table : tables) {
        if (!query.exec(QString("DROP TABLE IF EXISTS %1").arg(table))) {
            //qDEbug() << "Failed to drop table" << table << ":" << query.lastError().text();
        }
    }

    // 重新初始化数据库
    dbManager.initializeSqliteDatabase();
}

void Testdb::cleanupTestCase() {
    // 获取数据库实例
    QSqlDatabase db = DatabaseManager::instance().getDatabase();

    // 清除表
    QSqlQuery query(db);
    QStringList tables = { "Authentication", "PurchaseOrder", "Finance", "EnterRecord", "Inventory" };
    for (const QString& table : tables) {
        if (!query.exec(QString("DROP TABLE IF EXISTS %1").arg(table))) {
            //qDEbug() << "Failed to drop table" << table << ":" << query.lastError().text();
        }
    }

    // 关闭数据库连接
    db.close();
}

void Testdb::testGetTableRowCounts() {
    QList<int> rowCounts = DatabaseManager::instance().getTableRowCounts();
    QCOMPARE(rowCounts.size(), 5); // 确保返回了5个表的行数

    // 检查所有元素是否大于等于0
    for (int count : rowCounts) {
        QVERIFY(count >= 0);
    }
}

// Test methods for Authenciation table operations
void Testdb::testInsertAuthentication() {
    QSqlDatabase::database().transaction();
    QString username = "testuser";
    QString password = "testpassword";
    QString position = "employee";

    // Attempt to insert new authentication record
    QVERIFY(DatabaseManager::instance().insertAuthentication(username, password, position));

    QSqlQuery verifyQuery(DatabaseManager::instance().getDatabase());
    verifyQuery.prepare("SELECT username FROM Authentication WHERE username = :username");
    verifyQuery.bindValue(":username", username);

    QVERIFY(verifyQuery.exec());
    QVERIFY(verifyQuery.next());
    QCOMPARE(verifyQuery.value(0).toString(), username);

    QSqlDatabase::database().rollback();
}

void Testdb::testCheckAuthentication() {
    QSqlDatabase::database().transaction();
    // This record is in Authenciation table initially for testing
    QString username = "admin";
    QString password = "admin";
    QString position = "管理员";

    bool authenticationResult = DatabaseManager::instance().checkAuthentication(username, password, position);

    QVERIFY(authenticationResult);
    QSqlDatabase::database().rollback();
}

void Testdb::testUpdateAuthentication() {
    QSqlDatabase::database().transaction();
    int idToUpdate = 1;
    QString initialUsername = "admin";
    QString initialPassword = "admin";
    QString initialPosition = "管理员";

    // Verify the initial state
    {
        QSqlQuery verifyInitialQuery(DatabaseManager::instance().getDatabase());
        verifyInitialQuery.prepare("SELECT username, password, position FROM Authentication WHERE id = :id");
        verifyInitialQuery.bindValue(":id", idToUpdate);

        QVERIFY(verifyInitialQuery.exec());
        QVERIFY(verifyInitialQuery.next());
        QCOMPARE(verifyInitialQuery.value("username").toString(), initialUsername);
        QCOMPARE(verifyInitialQuery.value("password").toString(), initialPassword);
        QCOMPARE(verifyInitialQuery.value("position").toString(), initialPosition);
    }

    // New data for the first update
    QString newUsername1 = "newadmin";
    QString newPassword1 = "newpassword";
    QString newPosition1 = "财务管理员";

    // Perform the first update
    QVERIFY(DatabaseManager::instance().updateAuthentication(idToUpdate, newUsername1, newPassword1, newPosition1));

    // Verify that the record has been updated
    {
        QSqlQuery verifyQuery(DatabaseManager::instance().getDatabase());
        verifyQuery.prepare("SELECT username, password, position FROM Authentication WHERE id = :id");
        verifyQuery.bindValue(":id", idToUpdate);

        QVERIFY(verifyQuery.exec());
        QVERIFY(verifyQuery.next());
        QCOMPARE(verifyQuery.value("username").toString(), newUsername1);
        QCOMPARE(verifyQuery.value("password").toString(), newPassword1);
        QCOMPARE(verifyQuery.value("position").toString(), newPosition1);
    }

    // New data for the second update
    QString newUsername2 = "admin";
    QString newPassword2 = "admin";
    QString newPosition2 = "管理员";

    // Perform the second update
    QVERIFY(DatabaseManager::instance().updateAuthentication(idToUpdate, newUsername2, newPassword2, newPosition2));

    // Verify that the record has been updated again
    {
        QSqlQuery verifyQuery(DatabaseManager::instance().getDatabase());
        verifyQuery.prepare("SELECT username, password, position FROM Authentication WHERE id = :id");
        verifyQuery.bindValue(":id", idToUpdate);

        QVERIFY(verifyQuery.exec());
        QVERIFY(verifyQuery.next());
        QCOMPARE(verifyQuery.value("username").toString(), newUsername2);
        QCOMPARE(verifyQuery.value("password").toString(), newPassword2);
        QCOMPARE(verifyQuery.value("position").toString(), newPosition2);
    }
    QSqlDatabase::database().rollback();
}

void Testdb::testDeleteAuthentication() {
    QSqlDatabase::database().transaction();
    int idToDelete = 1; // Assuming there is a record with id 1 in the Authentication table

    // Attempt to delete authentication record
    QVERIFY(DatabaseManager::instance().deleteAuthentication(idToDelete));

    // Verify that the record with the deleted id does not exist in the database
    QSqlQuery verifyQuery(DatabaseManager::instance().getDatabase());
    verifyQuery.prepare("SELECT id FROM Authentication WHERE id = :id");
    verifyQuery.bindValue(":id", idToDelete);

    QVERIFY(verifyQuery.exec());
    QVERIFY(!verifyQuery.next()); // Expecting no results after deletion
    QSqlDatabase::database().rollback();
}

void Testdb::testGetAuthenticationModel() {
    QSqlDatabase::database().transaction();
    DatabaseManager& dbManager = DatabaseManager::instance();

    // Insert some sample authentication records for testing
    QSqlQuery query;
    query.prepare("INSERT INTO Authentication (username, password, position) VALUES (?, ?, ?)");
    query.addBindValue("user1");
    query.addBindValue("password1");
    query.addBindValue("管理员");
    if (!query.exec()) {
        //qDEbug() << "Error: Failed to insert sample data into Authentication table:" << query.lastError().text();
        return;
    }
    query.prepare("INSERT INTO Authentication (username, password, position) VALUES (?, ?, ?)");
    query.addBindValue("user2");
    query.addBindValue("password2");
    query.addBindValue("财务管理员");
    if (!query.exec()) {
        //qDEbug() << "Error: Failed to insert sample data into Authentication table:" << query.lastError().text();
        return;
    }

    // Retrieve the authentication model
    QSqlTableModel* model = dbManager.getAuthenticationModel();

    // Verify the number of rows in the model
    QCOMPARE(model->rowCount(), 3); // Expecting three rows (with initial one)

    // Verify the data in the model
    QCOMPARE(model->index(1, 1).data().toString(), QString("user1")); // username of the first record
    QCOMPARE(model->index(1, 2).data().toString(), QString("password1")); // password of the first record
    QCOMPARE(model->index(1, 3).data().toString(), QString("管理员")); // position of the first record

    QCOMPARE(model->index(2, 1).data().toString(), QString("user2")); // username of the second record
    QCOMPARE(model->index(2, 2).data().toString(), QString("password2")); // password of the second record
    QCOMPARE(model->index(2, 3).data().toString(), QString("财务管理员")); // position of the second record
    delete model;
    QSqlDatabase::database().rollback();
}

// Test methods for PurchaseOrder table operations
void Testdb::testPurchaseOrderHelperOfInsert() {
    // Prepare test data
    QString orderMaterialType = "Steel";
    int amount = 5;
    QString acceptDate = "2024-07-10";
    QString orderStatus = "未完成";
    int prepaid = 500;
    QString clientName = "John Doe";
    QString clientTEL = "1234567890";

    bool result =DatabaseManager::instance().insertPurchaseOrder(orderMaterialType, amount, acceptDate, orderStatus, prepaid, clientName, clientTEL);
    QVERIFY(result);
}

void Testdb::testInsertPurchaseOrder() {
    QSqlDatabase::database().transaction();
    DatabaseManager& dbManager = DatabaseManager::instance();

    testPurchaseOrderHelperOfInsert();
    // Prepare test data
    QString orderMaterialType = "Steel";
    int amount = 5;
    QString acceptDate = "2024-07-10";
    QString orderStatus = "已完成";
    int prepaid = 500;
    QString clientName = "John Doe";
    QString clientTEL = "1234567890";
    // Step 1: Insert a new purchase order
    bool result =DatabaseManager::instance().insertPurchaseOrder(orderMaterialType, amount, acceptDate, orderStatus, prepaid, clientName, clientTEL);
    QVERIFY(result);

    // Verify that the record was actually inserted
    QSqlQuery query(dbManager.getDatabase());
    query.prepare("SELECT * FROM PurchaseOrder WHERE orderMaterialType = :orderMaterialType AND amount = :amount AND acceptDate = :acceptDate AND orderStatus = :orderStatus AND prepaid = :prepaid AND clientName = :clientName AND clientTEL = :clientTEL");
    query.bindValue(":orderMaterialType", orderMaterialType);
    query.bindValue(":amount", amount);
    query.bindValue(":acceptDate", acceptDate);
    query.bindValue(":orderStatus", orderStatus);
    query.bindValue(":prepaid", prepaid);
    query.bindValue(":clientName", clientName);
    query.bindValue(":clientTEL", clientTEL);

    QVERIFY(query.exec());
    QVERIFY(query.next());  // There should be a matching record
    QSqlDatabase::database().rollback();
}

void Testdb::testGetPurchaseOrderModel() {
    QSqlDatabase::database().transaction();
    DatabaseManager& dbManager = DatabaseManager::instance();

    testPurchaseOrderHelperOfInsert();

    // Get the model
    QSqlTableModel* model = dbManager.getPurchaseOrderModel();
    QVERIFY(model != nullptr);

    // Check if the model has the correct number of columns
    QCOMPARE(model->columnCount(), 8);

    // Check column headers
    QCOMPARE(model->headerData(0, Qt::Horizontal).toString(), QObject::tr("ID"));
    QCOMPARE(model->headerData(1, Qt::Horizontal).toString(), QObject::tr("Order Material Type"));
    QCOMPARE(model->headerData(2, Qt::Horizontal).toString(), QObject::tr("Amount"));
    QCOMPARE(model->headerData(3, Qt::Horizontal).toString(), QObject::tr("Accept Date"));
    QCOMPARE(model->headerData(4, Qt::Horizontal).toString(), QObject::tr("Condition"));
    QCOMPARE(model->headerData(5, Qt::Horizontal).toString(), QObject::tr("Prepaid"));
    QCOMPARE(model->headerData(6, Qt::Horizontal).toString(), QObject::tr("Client Name"));
    QCOMPARE(model->headerData(7, Qt::Horizontal).toString(), QObject::tr("Client TEL"));
    delete model;
    QSqlDatabase::database().rollback();
}

void Testdb::testMarkPurchaseOrderAsCompleted() {
    QSqlDatabase::database().transaction();
    DatabaseManager& dbManager = DatabaseManager::instance();
    // Insert a test record
    QString orderMaterialType = "Steel";
    int amount = 5;
    QString acceptDate = "2024-07-10";
    QString orderStatus = "未完成";
    int prepaid = 500;
    QString clientName = "John Doe";
    QString clientTEL = "1234567890";

    testPurchaseOrderHelperOfInsert();

    // Get the ID of the inserted record
    QSqlQuery query(dbManager.getDatabase());
    query.prepare("SELECT id FROM PurchaseOrder WHERE orderMaterialType = :orderMaterialType AND amount = :amount AND acceptDate = :acceptDate AND orderStatus = :orderStatus AND prepaid = :prepaid AND clientName = :clientName AND clientTEL = :clientTEL");
    query.bindValue(":orderMaterialType", orderMaterialType);
    query.bindValue(":amount", amount);
    query.bindValue(":acceptDate", acceptDate);
    query.bindValue(":orderStatus", orderStatus);
    query.bindValue(":prepaid", prepaid);
    query.bindValue(":clientName", clientName);
    query.bindValue(":clientTEL", clientTEL);
    QVERIFY(query.exec());
    QVERIFY(query.next());
    int orderId = query.value(0).toInt();

    // Mark the order as completed
    bool markCompletedResult = dbManager.markPurchaseOrderAsCompleted(orderId);
    QVERIFY(markCompletedResult);

    // Verify that the orderStatus is set to "已完成"
    QSqlQuery checkQuery(dbManager.getDatabase());
    checkQuery.prepare("SELECT orderStatus FROM PurchaseOrder WHERE id = :id");
    checkQuery.bindValue(":id", orderId);
    QVERIFY(checkQuery.exec());
    QVERIFY(checkQuery.next());
    QCOMPARE(checkQuery.value(0).toString(), "已完成");

    // Attempt to mark the already completed order as completed again
    bool markCompletedAgainResult = dbManager.markPurchaseOrderAsCompleted(orderId);
    QVERIFY(!markCompletedAgainResult); // This should fail since the order is already completed

    testPurchaseOrderHelperOfInsert();

    // Get the ID of the newly inserted record
    query.prepare("SELECT id FROM PurchaseOrder WHERE orderMaterialType = :orderMaterialType AND amount = :amount AND acceptDate = :acceptDate AND orderStatus = :orderStatus AND prepaid = :prepaid AND clientName = :clientName AND clientTEL = :clientTEL ORDER BY id DESC LIMIT 1");
    query.bindValue(":orderMaterialType", orderMaterialType);
    query.bindValue(":amount", amount);
    query.bindValue(":acceptDate", acceptDate);
    query.bindValue(":orderStatus", orderStatus);
    query.bindValue(":prepaid", prepaid);
    query.bindValue(":clientName", clientName);
    query.bindValue(":clientTEL", clientTEL);
    QVERIFY(query.exec());
    QVERIFY(query.next());
    int newOrderId = query.value(0).toInt();

    // Verify the new order ID is different from the first order ID
    QVERIFY(newOrderId != orderId);

    // Test marking a non-existent order ID as completed
    int nonExistentOrderId = newOrderId + 100000000; // Assuming this ID does not exist
    bool markNonExistentResult = dbManager.markPurchaseOrderAsCompleted(nonExistentOrderId);
    QVERIFY(!markNonExistentResult);
    QSqlDatabase::database().rollback();
}

void Testdb::testGetPurchaseOrderById() {
    QSqlDatabase::database().transaction();
    DatabaseManager& dbManager = DatabaseManager::instance();

    // Insert a test record
    QString orderMaterialType = "Steel";
    int amount = 5;
    QString acceptDate = "2024-07-10";
    QString orderStatus = "未完成";
    int prepaid = 500;
    QString clientName = "John Doe";
    QString clientTEL = "1234567890";

    testPurchaseOrderHelperOfInsert();
    // Get the ID of the inserted record
    QSqlQuery query(dbManager.getDatabase());
    query.prepare("SELECT id FROM PurchaseOrder WHERE orderMaterialType = :orderMaterialType AND amount = :amount AND acceptDate = :acceptDate AND orderStatus = :orderStatus AND prepaid = :prepaid AND clientName = :clientName AND clientTEL = :clientTEL");
    query.bindValue(":orderMaterialType", orderMaterialType);
    query.bindValue(":amount", amount);
    query.bindValue(":acceptDate", acceptDate);
    query.bindValue(":orderStatus", orderStatus);
    query.bindValue(":prepaid", prepaid);
    query.bindValue(":clientName", clientName);
    query.bindValue(":clientTEL", clientTEL);
    QVERIFY(query.exec());
    QVERIFY(query.next());
    int orderId = query.value(0).toInt();

    // Retrieve the order by ID
    QSqlTableModel* model = dbManager.getPurchaseOrderById(orderId);
    QVERIFY(model != nullptr);

    // Verify the retrieved data
    QCOMPARE(model->rowCount(), 1); // Ensure exactly one row is returned

    delete model;
    QSqlDatabase::database().rollback();
}

void Testdb::testGetPurchaseOrderDateAndCondition() {
    QSqlDatabase::database().transaction();
    DatabaseManager& dbManager = DatabaseManager::instance();
    // Insert test records
    bool insertResult1 = dbManager.insertPurchaseOrder("Steel", 5, "2024-07-10", "未完成", 500, "John Doe", "1234567890");
    bool insertResult2 = dbManager.insertPurchaseOrder("Steel", 5, "2024-07-11", "已完成", 500, "John Doe", "1234567890");
    QVERIFY(insertResult1);
    QVERIFY(insertResult2);

    // Retrieve purchase order dates and orderStatuss
    QList<QPair<QString, QString>> result = dbManager.getPurchaseOrderDateAndCondition();

    // Verify the retrieved data
    QVERIFY(result.size() >= 2);

    bool foundAcceptDate1 = false;
    bool foundAcceptDate2 = false;

    for (const QPair<QString, QString>& pair : result) {
        if (pair.first == "2024-07-10" && pair.second == "未完成") {
            foundAcceptDate1 = true;
        } else if (pair.first == "2024-07-11" && pair.second == "已完成") {
            foundAcceptDate2 = true;
        }
    }
    QVERIFY(foundAcceptDate1);
    QVERIFY(foundAcceptDate2);
    QSqlDatabase::database().rollback();
}

// Test methods for Finance table
void Testdb::testInsertFinanceRecord() {
    QSqlDatabase::database().transaction();
    DatabaseManager& dbManager = DatabaseManager::instance();

    // Create a valid matchingId first
    testPurchaseOrderHelperOfInsert();
    // Insert a finance record with a valid matchingId
    bool insertResult = dbManager.insertFinanceRecord(1, "首款", "2024-07-10", 1000, 5000, 4000, 1000);
    QVERIFY(insertResult);
    QSqlDatabase::database().rollback();
}

void Testdb::testGetFinanceTableModel() {
    QSqlDatabase::database().transaction();
    DatabaseManager& dbManager = DatabaseManager::instance();

    testPurchaseOrderHelperOfInsert();
    bool insertResult = dbManager.insertFinanceRecord(1, "首款", "2024-07-10", 1000, 5000, 4000, 1000);
    QVERIFY(insertResult);

    // Retrieve the finance table model
    QSqlTableModel* model = dbManager.getFinanceTableModel();
    QVERIFY(model != nullptr);

    // Verify the table structure and headers
    QCOMPARE(model->tableName(), QString("Finance"));
    QCOMPARE(model->columnCount(), 8);

    QCOMPARE(model->headerData(0, Qt::Horizontal).toString(), QString("ID"));
    QCOMPARE(model->headerData(1, Qt::Horizontal).toString(), QString("Matching ID"));
    QCOMPARE(model->headerData(2, Qt::Horizontal).toString(), QString("Record Type"));
    QCOMPARE(model->headerData(3, Qt::Horizontal).toString(), QString("Record Date"));
    QCOMPARE(model->headerData(4, Qt::Horizontal).toString(), QString("Amount"));
    QCOMPARE(model->headerData(5, Qt::Horizontal).toString(), QString("Total Income"));
    QCOMPARE(model->headerData(6, Qt::Horizontal).toString(), QString("Total Outcome"));
    QCOMPARE(model->headerData(7, Qt::Horizontal).toString(), QString("Total Interest"));
    delete model;
    QSqlDatabase::database().rollback();
}

// void Testdb::testGetFinanceRecordById() {}

void Testdb::testGetFinanceLastTotal() {
    QSqlDatabase::database().transaction();
    DatabaseManager& dbManager = DatabaseManager::instance();

    // Insert some sample finance records for testing
    dbManager.insertFinanceRecord(1, "首款", "2024-07-10", 1000, 5000, 4000, 1000);

    // Retrieve the last finance totals
    QList<int> lastTotals = dbManager.getFinanceLastTotal();

    // Verify the size of the returned list
    QCOMPARE(lastTotals.size(), 3); // Expecting three elements for TotalIncome, TotalOutcome, and TotalInterest

    // Verify the values retrieved
    QCOMPARE(lastTotals.at(0), 5000); // TotalIncome from the last record inserted
    QCOMPARE(lastTotals.at(1), 4000); // TotalOutcome from the last record inserted
    QCOMPARE(lastTotals.at(2), 1000); // TotalInterest from the last record inserted
    QSqlDatabase::database().rollback();
}

// void Testdb::testGetFinanceRecordsForLinePlot() {}

// Test methods for EnterRecord table
void Testdb::testInsertEnterRecord() {
    QSqlDatabase::database().transaction();
    DatabaseManager& dbManager = DatabaseManager::instance();

    // Prepare test data
    QString enterDate = "2024-07-15";
    QString enterMaterialType = "MaterialX";
    int enterAmount = 100;
    int unitPrice = 50;
    int totalPrice = enterAmount * unitPrice;

    // Insert the enter record
    bool insertResult = dbManager.insertEnterRecord(enterDate, enterMaterialType, enterAmount, unitPrice, totalPrice);

    // Verify the insertion result
    QVERIFY(insertResult); // Ensure insertion succeeded without errors

    // Retrieve the inserted record for verification
    QSqlTableModel* model = dbManager.getEnterRecordById(1); // Assuming the first record inserted has ID 1

    // Verify that the retrieved record matches the inserted data
    QCOMPARE(model->rowCount(), 1); // Expecting exactly one row

    // Verify each field in the model
    QCOMPARE(model->data(model->index(0, model->fieldIndex("EnterDate"))).toString(), enterDate);
    QCOMPARE(model->data(model->index(0, model->fieldIndex("EnterMaterialType"))).toString(), enterMaterialType);
    QCOMPARE(model->data(model->index(0, model->fieldIndex("EnterAmount"))).toInt(), enterAmount);
    QCOMPARE(model->data(model->index(0, model->fieldIndex("unitPrice"))).toInt(), unitPrice);
    QCOMPARE(model->data(model->index(0, model->fieldIndex("totalPrice"))).toInt(), totalPrice);
    QSqlDatabase::database().rollback();
}

void Testdb::testGetEnterRecordModel() {
    QSqlDatabase::database().transaction();
    DatabaseManager& dbManager = DatabaseManager::instance();

    // Insert test data to ensure there is at least one record in EnterRecord table
    QString enterDate = "2024-07-15";
    QString enterMaterialType = "MaterialX";
    int enterAmount = 100;
    int unitPrice = 50;
    int totalPrice = enterAmount * unitPrice;
    dbManager.insertEnterRecord(enterDate, enterMaterialType, enterAmount, unitPrice, totalPrice);

    // Get the EnterRecord model from the database manager
    QSqlTableModel* model = dbManager.getEnterRecordModel();

    // Verify that the model is not null
    QVERIFY(model != nullptr);

    // Verify column count
    QCOMPARE(model->columnCount(), 6); // Assuming there are 6 columns in EnterRecord table

    // Verify column headers
    QCOMPARE(model->headerData(0, Qt::Horizontal).toString(), QString("ID"));
    QCOMPARE(model->headerData(1, Qt::Horizontal).toString(), QString("Enter Date"));
    QCOMPARE(model->headerData(2, Qt::Horizontal).toString(), QString("Material Type"));
    QCOMPARE(model->headerData(3, Qt::Horizontal).toString(), QString("Enter Amount"));
    QCOMPARE(model->headerData(4, Qt::Horizontal).toString(), QString("Unit Price"));
    QCOMPARE(model->headerData(5, Qt::Horizontal).toString(), QString("Total Price"));

    // Verify row count (expecting at least one row)
    QVERIFY(model->rowCount() >= 1);
    QSqlDatabase::database().rollback();
}

void Testdb::testGetEnterRecordById() {
    QSqlDatabase::database().transaction();
    DatabaseManager& dbManager = DatabaseManager::instance();

    // Insert a test EnterRecord to ensure there is at least one record with known ID
    QString enterDate = "2024-07-15";
    QString enterMaterialType = "MaterialX";
    int enterAmount = 100;
    int unitPrice = 50;
    int totalPrice = enterAmount * unitPrice;
    bool insertResult = dbManager.insertEnterRecord(enterDate, enterMaterialType, enterAmount, unitPrice, totalPrice);
    QVERIFY(insertResult); // Verify insertion was successful

    // Retrieve the ID of the inserted record (assuming it's the first one)
    QSqlQuery getIdQuery(dbManager.getDatabase());
    getIdQuery.prepare("SELECT id FROM EnterRecord LIMIT 1");
    if (!getIdQuery.exec() || !getIdQuery.next()) {
        QFAIL("Failed to retrieve ID of inserted EnterRecord");
    }
    int id = getIdQuery.value(0).toInt();

    // Get the EnterRecord model by ID
    QSqlTableModel* model = dbManager.getEnterRecordById(id);

    // Verify that the model is not null
    QVERIFY(model != nullptr);

    // Verify column count
    QCOMPARE(model->columnCount(), 6); // Assuming there are 6 columns in EnterRecord table

    // Verify column headers
    QCOMPARE(model->headerData(0, Qt::Horizontal).toString(), QString("ID"));
    QCOMPARE(model->headerData(1, Qt::Horizontal).toString(), QString("Enter Date"));
    QCOMPARE(model->headerData(2, Qt::Horizontal).toString(), QString("Material Type"));
    QCOMPARE(model->headerData(3, Qt::Horizontal).toString(), QString("Enter Amount"));
    QCOMPARE(model->headerData(4, Qt::Horizontal).toString(), QString("Unit Price"));
    QCOMPARE(model->headerData(5, Qt::Horizontal).toString(), QString("Total Price"));

    // Verify row count (expecting exactly one row since we queried by ID)
    QCOMPARE(model->rowCount(), 1);
    QSqlDatabase::database().rollback();
}

// Test methods for Inventory table
void Testdb::testChangeInventory() {
    QSqlDatabase::database().transaction();
    DatabaseManager& dbManager = DatabaseManager::instance();

    // Test case 1: Insert new inventory record
    QString rawMaterialType1 = "Steel";
    int initialAmount1 = 100;

    QVERIFY(dbManager.changeInventory(rawMaterialType1, initialAmount1));

    // Verify the inserted record
    QSqlQuery verifyQuery(dbManager.getDatabase());
    verifyQuery.prepare("SELECT amount FROM Inventory WHERE rawMaterialType = :rawMaterialType");
    verifyQuery.bindValue(":rawMaterialType", rawMaterialType1);
    QVERIFY(verifyQuery.exec());
    QVERIFY(verifyQuery.next());
    int amountAfterInsert = verifyQuery.value(0).toInt();
    QCOMPARE(amountAfterInsert, initialAmount1);

    // Test case 2: Update existing inventory record
    int addAmount = -50;
    int expectedAmount = initialAmount1 + addAmount;

    QVERIFY(dbManager.changeInventory(rawMaterialType1, addAmount));

    // Verify the updated record
    verifyQuery.exec();
    QVERIFY(verifyQuery.next());
    int amountAfterUpdate = verifyQuery.value(0).toInt();
    QCOMPARE(amountAfterUpdate, expectedAmount);
    QSqlDatabase::database().rollback();
}

void Testdb::testgetInventoryForPiePlot() {
    QSqlDatabase::database().transaction();
    DatabaseManager& dbManager = DatabaseManager::instance();

    // 插入测试记录
    QVERIFY(dbManager.changeInventory("A", 10));
    QVERIFY(dbManager.changeInventory("B", 20));

    // 获取库存列表
    QList<QPair<QString, int>> inventoryList = dbManager.getInventoryForPiePlot();

    // 验证获取到的列表
    QCOMPARE(inventoryList.size(), 2);
    QVERIFY(inventoryList.contains(QPair<QString, int>("A", 10)));
    QVERIFY(inventoryList.contains(QPair<QString, int>("B", 20)));
    QSqlDatabase::database().rollback();
}

void Testdb::testGetInventoryByType() {
    QSqlDatabase::database().transaction();
    DatabaseManager& dbManager = DatabaseManager::instance();

    QString rawMaterialType1 = "Steel";
    int initialAmount1 = 100;

    QVERIFY(dbManager.changeInventory(rawMaterialType1, initialAmount1));
    QSqlTableModel* model = dbManager.getInventoryByType(rawMaterialType1);
    QVERIFY(model != nullptr);
    QCOMPARE(model->rowCount(), 1);
    QCOMPARE(model->data(model->index(0, 2)).toInt(), initialAmount1);
    delete model;
    QSqlDatabase::database().rollback();
}
